package com.longview.io.common.utils;

import java.util.ArrayList;
import java.util.List;

import com.longview.io.modules.sys.entity.MyPoint;

public class MapAreaUtils {
    private static double EARTH_RADIUS = 6371.393;  
    private static double rad(double d)  
    {  
       return d * Math.PI / 180.0;  
    }  
	public static void main(String args[]){
		double jl = GetDistance(111.69205522489281,40.86757059308859,111.69600776913671,40.86807524714442);
		 System.out.println(jl);
		
		MyPoint p1 = new MyPoint(111.69205522489281,40.86757059308859);
		MyPoint p2 = new MyPoint(111.69600776913671,40.86807524714442);
		MyPoint p3 = new MyPoint(111.6964389557815,40.86634304001619);
		MyPoint p4 = new MyPoint(111.69232471654581,40.86579745351201);  
		   List list = new ArrayList();
		   list.add(p1);
		   list.add(p2);
		   list.add(p3);
		   list.add(p4);
		   MapAreaUtils t = new MapAreaUtils();
		   double area = t.getArea1(list);
		   System.out.println(area);
		}
    public static double GetDistance(double lat1, double lng1, double lat2, double lng2)  
    {  
       double radLat1 = rad(lat1);  
       double radLat2 = rad(lat2);  
       double a = radLat1 - radLat2;      
       double b = rad(lng1) - rad(lng2);  
       double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2),2) +   
        Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2),2)));  
       s = s * EARTH_RADIUS;  
       s = Math.round(s * 1000);  
       return s;  
    }
		public double getArea(List<MyPoint> list)
		{
		   //S = 0.5 * ( (x0*y1-x1*y0) + (x1*y2-x2*y1) + ... + (xn*y0-x0*yn) )

		   double area = 0.00;
		   for(int i = 0;i<list.size();i++){
		    if(i<list.size()-1){
		    	MyPoint p1 = list.get(i);
		    	MyPoint p2 = list.get(i+1);
		     area += p1.getX()*p2.getY() - p2.getX()*p1.getY();
		    }else{
		    	MyPoint pn = list.get(i);
		    	MyPoint p0 = list.get(0);
		     area += pn.getX()*p0.getY()- p0.getX()*pn.getY();
		    }
		   
		   }
		   area = area/2.00;
		  
		   return area;
		}
		
		public double getArea1(List<MyPoint> list)
		{
	        double totalArea = 0;// 初始化总面积
	        double LowX = 0.0; 
	        double LowY = 0.0; 
	        double MiddleX = 0.0;
	        double MiddleY = 0.0;
	        double HighX = 0.0;
	        double HighY = 0.0;
	        double AM = 0.0;
	        double BM = 0.0;
	        double CM = 0.0;
	        double AL = 0.0;
	        double BL = 0.0;
	        double CL = 0.0;
	        double AH = 0.0;
	        double BH = 0.0;
	        double CH = 0.0;
	        double CoefficientL = 0.0;
	        double CoefficientH = 0.0;
	        double ALtangent = 0.0;
	        double BLtangent = 0.0;
	        double CLtangent = 0.0;
	        double AHtangent = 0.0;
	        double BHtangent = 0.0;
	        double CHtangent = 0.0;
	        double ANormalLine = 0.0;
	        double BNormalLine = 0.0;
	        double CNormalLine = 0.0;
	        double OrientationValue = 0.0;
	        double AngleCos = 0.0;
	        double Sum1 = 0.0;
	        double Sum2 = 0.0;
	        double Count2 = 0;
	        double Count1 = 0;
	        double Sum = 0.0;
	        double Radius = 6378137.0;// ,WGS84椭球半径
	        int Count = list.size();
	          for ( int i = 0; i < Count; i++) {
	                if (i == 0) {
	                    LowX = list.get(Count-1).lng * Math.PI / 180;
	                    LowY = list.get(Count-1).lat * Math.PI / 180;
	                    MiddleX =  list.get(0).lng * Math.PI / 180;
	                    MiddleY = list.get(0).lat * Math.PI / 180;
	                    HighX = list.get(1).lng * Math.PI / 180;
	                    HighY = list.get(1).lat * Math.PI / 180;
	                } else if (i == Count - 1) {
	                    LowX = list.get(Count-2).lng * Math.PI / 180;
	                    LowY = list.get(Count-2).lat * Math.PI / 180;
	                    MiddleX = list.get(Count-1).lng * Math.PI / 180;
	                    MiddleY = list.get(Count-1).lat * Math.PI / 180;
	                    HighX = list.get(0).lng * Math.PI / 180;
	                    HighY = list.get(0).lat * Math.PI / 180;
	                } else {
	                    LowX = list.get(i-1).lng * Math.PI / 180;
	                    LowY = list.get(i-1).lat * Math.PI / 180;
	                    MiddleX = list.get(i).lng * Math.PI / 180;
	                    MiddleY = list.get(i).lat * Math.PI / 180;
	                    HighX = list.get(i+1).lng * Math.PI / 180;
	                    HighY = list.get(i+1).lat * Math.PI / 180;
	                }
	                AM = Math.cos(MiddleY) * Math.cos(MiddleX);
	                BM = Math.cos(MiddleY) * Math.sin(MiddleX);
	                CM = Math.sin(MiddleY);
	                AL = Math.cos(LowY) * Math.cos(LowX);
	                BL = Math.cos(LowY) * Math.sin(LowX);
	                CL = Math.sin(LowY);
	                AH = Math.cos(HighY) * Math.cos(HighX);
	                BH = Math.cos(HighY) * Math.sin(HighX);
	                CH = Math.sin(HighY);
	                CoefficientL = (AM * AM + BM * BM + CM * CM)/ (AM * AL + BM * BL + CM * CL);
	                CoefficientH = (AM * AM + BM * BM + CM * CM)/ (AM * AH + BM * BH + CM * CH);
	                ALtangent = CoefficientL * AL - AM;
	                BLtangent = CoefficientL * BL - BM;
	                CLtangent = CoefficientL * CL - CM;
	                AHtangent = CoefficientH * AH - AM;
	                BHtangent = CoefficientH * BH - BM;
	                CHtangent = CoefficientH * CH - CM;
	                AngleCos = (AHtangent * ALtangent + BHtangent * BLtangent + CHtangent* CLtangent)/ (Math.sqrt(AHtangent * AHtangent + BHtangent* BHtangent + CHtangent * CHtangent) * Math.sqrt(ALtangent * ALtangent + BLtangent* BLtangent + CLtangent * CLtangent));
	                AngleCos = Math.acos(AngleCos);
	                ANormalLine = BHtangent * CLtangent - CHtangent * BLtangent;
	                BNormalLine = 0 - (AHtangent * CLtangent - CHtangent* ALtangent);
	                CNormalLine = AHtangent * BLtangent - BHtangent * ALtangent;
	                if (AM != 0)
	                    OrientationValue = ANormalLine / AM;
	                else if (BM != 0)
	                    OrientationValue = BNormalLine / BM;
	                else
	                    OrientationValue = CNormalLine / CM;
	                if (OrientationValue > 0) {
	                    Sum1 += AngleCos;
	                    Count1++;
	                } else {
	                    Sum2 += AngleCos;
	                    Count2++;
	                }
	            }

	            double tempSum1, tempSum2;
	            tempSum1 = Sum1 + (2 * Math.PI * Count2 - Sum2);
	            tempSum2 = (2 * Math.PI * Count1 - Sum1) + Sum2;
	            if (Sum1 > Sum2) {
	                if ((tempSum1 - (Count - 2) * Math.PI) < 1)
	                    Sum = tempSum1;
	                else
	                    Sum = tempSum2;
	            } else {
	                if ((tempSum2 - (Count - 2) * Math.PI) < 1)
	                    Sum = tempSum2;
	                else
	                    Sum = tempSum1;
	            }
	            totalArea = (Sum - (Count - 2) * Math.PI) * Radius * Radius;

	            return totalArea; // 返回总面积
		}
		
}
